//
//  CZStatusDAL.swift
//  iOSWeibo10
//
//  Created by itcast on 16/5/26.
//  Copyright © 2016年 itcast. All rights reserved.
//

import UIKit

/// 专门加载微博数据,有可能从本地数据库,也有可能从网络

/*
    1.先去数据库查找 2
    2.数据有直接返回数据库中的数据
    3.没有数据,发送网络请求去服务器加载数据
    4.服务器加载到数据,保存到数据库中 1
    5.将服务器返回的数据返回给调用的人
*/
class CZStatusDAL: NSObject {

    static let sharedStatusDAL = CZStatusDAL()
    
    let cacheTime: NSTimeInterval = 5 //7 * 24 * 60 * 60
    
    private override init() {
        super.init()
    }
    
    /**
     删除超时的微博.7天以前
     */
    func deleteOverTimeStatus() {
        let overDate = NSDate(timeIntervalSinceNow: -cacheTime)
        print("overDate: \(overDate)")
        
        let df = NSDateFormatter()
        // 时间格式
        df.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
        let overDateString = df.stringFromDate(overDate)
        
        let sqlString = "DELETE FROM T_Status WHERE createTime < '\(overDateString)';"
        print("overDateString: \(overDateString)")
        
        CZSQLiteManager.sharedManager.dbQueue.inDatabase { (db) -> Void in
            if db.executeUpdate(sqlString, withArgumentsInArray: nil) {
                print("清除数据成功了")
            } else {
                print("清除数据失败了")
            }
        }
    }
    
    /**
     加载微博数据,有可能从本地数据库,也有可能从网络
     */
    func loadStatus(since_id: Int64, max_id: Int64, loadStatusCallback: (statuses: [[String: AnyObject]]?, error: NSError?) -> ()) {
        // 1.先去数据库查找 2
        loadCacheStatus(since_id, max_id: max_id) { (statusesArray) -> () in
            if statusesArray.count > 0 {
                // 2.数据有直接返回数据库中的数据
                loadStatusCallback(statuses: statusesArray, error: nil)
                return
            }
            
            // 3.没有数据,发送网络请求去服务器加载数据
            guard let access_token = CZUserAccountViewModel.sharedInstance.userAccount?.access_token else {
                CZPrint(items: "access_token没有值,不去请求微博数据")
                return
            }
            // 看API
            // urlString
            let urlString = "2/statuses/home_timeline.json"
            // 参数
            var parameters: [String: AnyObject] = [
                "access_token" : access_token
            ]
            
            if since_id > 0 {
                // 别人传了 since_id,拼接since_id
                parameters["since_id"] = NSNumber(longLong: since_id)
            } else if max_id > 0 {
                // 别人传了 max_id,拼接max_id
                parameters["max_id"] = NSNumber(longLong: max_id - 1)
            }
            // 发送请求
            CZNetworkTool.sharedInstance.request(RequestMethod.GET, URLString: urlString, parameters: parameters, success: { (_, responseObject) -> Void in
                // 请求成功
                if let result = responseObject as? [String: AnyObject] {
                    // 返回的数据是字典
                    // 获取到所有的微博数据   [Int] [[String: AnyObject]]
                    if let statuses = result["statuses"] as? [[String: AnyObject]] {
                        // 4.服务器加载到数据,保存到数据库中 1
                        self.saveStatus(statuses)
                        // 5.将服务器返回的数据返回给调用的人
                        loadStatusCallback(statuses: statuses, error: nil)
                    }
                }
                
                }) { (_, error) -> Void in
                    loadStatusCallback(statuses: nil, error: error)
            }
        }
    }
    
    /**
     从数据库中加载微博数据
     
     - parameter since_id: since_id description
     - parameter max_Id:   max_Id description
     */
    private func loadCacheStatus(since_id: Int64, max_id: Int64, loadCacheStatusCallback: (statusesArray: [[String: AnyObject]]) -> ()) {
        let uid = CZUserAccountViewModel.sharedInstance.userAccount?.uid
        assert(uid != nil, "uid不能为空")
        
        var sqlString = "SELECT * FROM T_Status \n"
        
        if since_id > 0 {
            // 下拉刷新,加载比since_id大的微博
            sqlString += "WHERE statusId > \(since_id) AND userId = \(uid!)\n"
        } else if max_id > 0 {
            // 上拉加载,加载比max_Id小的微博
            sqlString += "WHERE statusId < \(max_id) AND userId = \(uid!)\n"
        } else {
            sqlString += "WHERE userId = \(uid!) \n"
        }
        
        sqlString += "ORDER BY statusId DESC LIMIT 20;"
        
        print("sqlString: \(sqlString)")
        CZSQLiteManager.sharedManager.dbQueue.inDatabase { (db) -> Void in
            let resultSet = db.executeQuery(sqlString, withArgumentsInArray: nil)
            
            var statusesArray = [[String: AnyObject]]()
            
            while resultSet.next() {
                let statusString = resultSet.stringForColumn("status")
//                print("加载数据库微博数据: \(statusString)")
                // String -> NSData -> 字典
                let data = statusString.dataUsingEncoding(NSUTF8StringEncoding)!
                
                do {
                    let dict = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0)) as! [String: AnyObject]
                    
                    // 将转好的字典放到数组中
                    statusesArray.append(dict)
                } catch {
                    print("json序列化失败了")
                }
            }
            
            // 所有的字典都放到数组中了
            loadCacheStatusCallback(statusesArray: statusesArray)
        }
    }
    
    /**
     保存微博数据
     
     - parameter statusesArray: 微博字典数组
     */
    private func saveStatus(statusesArray: [[String: AnyObject]]) {
        
        let userId = CZUserAccountViewModel.sharedInstance.userAccount?.uid
        
        assert(userId != nil, "没有uid")
        
        CZSQLiteManager.sharedManager.dbQueue.inTransaction { (db, rollback) -> Void in
            let sqlString = "INSERT INTO T_Status (statusId, status, userId) VALUES (?, ?, ?);"
            for dict in statusesArray {
                let statusId = dict["id"] as! NSNumber
                // NSNumber(longLong: statusId)
                // 直接将字典保存到数据库中到时候加载不出来
                // 字典转字符串 字典 -> NSData -> String
                // throws表示一个方法会抛出异常
                // 1.强制try dataWithJSONObject出现异常,立马挂了
                // 2.do {} catch {}
//                let data = try! NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions.PrettyPrinted)
                do {
                    let data = try NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions(rawValue: 0))
                    
                    let status = String(data: data, encoding: NSUTF8StringEncoding)!
                    
                    if !db.executeUpdate(sqlString, withArgumentsInArray: [statusId, status, userId!]) {
                        rollback.memory = true
                        break
                    }
                } catch let error as NSError {
                    // dataWithJSONObject出现异常会走这里,程序不会挂掉,还会接着跑
                    print("出了异常我走1: \(error)")
                }
                
            }
            
            print("添加了\(statusesArray.count) 条微博到数据库")
        }
    }
}
